package com.je.gateway.util;

import javax.servlet.http.HttpServletRequest;

/**
 * CIDR地址工具集
 */
public class IpUtil {

    public static String getIpAddress(HttpServletRequest request) {
        String ip = "";
        try {
            // 获取请求主机IP地址,如果通过代理进来，则透过防火墙获取真实IP地址
            ip = request.getHeader("X-Forwarded-For");
            if (ip != null && ip.length() > 0 && !"unKnown".equalsIgnoreCase(ip)) {
                // 多次反向代理后会有多个ip值，第一个ip才是真实ip
                int index = ip.indexOf(",");
                if (index != -1) {
                    return ip.substring(0, index);
                } else {
                    return ip;
                }
            }
            ip = request.getHeader("X-Real-IP");
            if (ip != null && ip.length() > 0 && !"unKnown".equalsIgnoreCase(ip)) {
                return ip;
            }
            ip = request.getRemoteAddr();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ip;
    }

    /**
     * 判断
     * @param ip
     * @param cidr
     * @return
     */
    public static boolean isInRange(String ip, String cidr) {
        // 以'.'为分隔拆分IP地址存入字符串数组ips
        String[] ips = ip.split("\\.");
        // 通过移位和或运算把IP地址由字符串数组转化为整数
        int ipAddr = (Integer.parseInt(ips[0]) << 24) | (Integer.parseInt(ips[1]) << 16)
                | (Integer.parseInt(ips[2]) << 8) | (Integer.parseInt(ips[3]));
        // 取出指定网段的子网掩码,即'/'后的数字,此为CIDR斜线记法
        int type = Integer.parseInt(cidr.replaceAll(".*/", ""));
        // 转化为整数表示
        int mask = 0xFFFFFFFF << (32 - type);
        // 取出子网IP
        String[] netIps = cidr.replaceAll("/.*", "").split("\\.");
        // 通过移位和或运算把子网IP由字符串数组转化为整数
        int netAddr = (Integer.parseInt(netIps[0]) << 24) | (Integer.parseInt(netIps[1]) << 16)
                | (Integer.parseInt(netIps[2]) << 8) | (Integer.parseInt(netIps[3]));
        // 两个IP分别与掩码做与运算,结果相等则返回True
        return (ipAddr & mask) == (netAddr & mask);

    }

}
